/*
 * @Author: liuzelin
 * @Date: 2024-04-06 12:28:15
 * @LastEditors: liuzelin
 * @LastEditTime: 2024-05-12 11:37:26
 * @Description: file content
 */
#pragma once

#include <string>
#include <cstdint>

#include "panda_export.hpp"

namespace Panda {
class PANDA_EXPORT SocketAddress {
 public:
  explicit SocketAddress(const char *ip, uint16_t port);
  explicit SocketAddress(const char *addr);
  explicit SocketAddress() = default;
  virtual ~SocketAddress() = default;
  bool operator == (const SocketAddress& other) { return this->ip == other.ip && this->port == other.port; }
  const std::string& ToString() const { return addr_str_; }
  const char *Ip() const { return this->ip.c_str(); }
  uint16_t Port() const { return port; }

 private:
  std::string addr_str_ = "";
  std::string ip = "";
  uint16_t port = 0;
};

class PANDA_EXPORT UDPSocketListener {
 public:
  virtual void OnReadFrom(char *data, size_t len,
                          const SocketAddress &from) = 0;
  virtual void OnSend(char *data, size_t len, int status, const char *msg) = 0;
};

class PANDA_EXPORT UDPSocket {
 public:
  virtual ~UDPSocket() = default;
  virtual bool Bind(const SocketAddress &ip) = 0;
  virtual void SendTo(char *data, size_t len, SocketAddress &to) = 0;
  virtual void SetSocketListener(UDPSocketListener *l) = 0;
  virtual const SocketAddress &GetLocal() = 0;
};
class TCPSocket;
class PANDA_EXPORT TCPSocketListener {
 public:
  virtual void OnRead(char *data, size_t len) = 0;
  virtual void OnSend(char* data, size_t len, int status) = 0;
  virtual void OnConnected(TCPSocket *s) = 0;
  virtual void OnNewConnect(TCPSocket *s) = 0;
};

class PANDA_EXPORT TCPSocket {
 public:
  virtual ~TCPSocket() = default;
  virtual const SocketAddress &GetLocal() = 0;
  virtual const SocketAddress &GetRemote() = 0;
  virtual void SetSocketListener(TCPSocketListener *l) = 0;
  virtual bool Bind(const SocketAddress &ip) = 0;
  virtual void Connect(const SocketAddress &remote) = 0;
  virtual int Send(char *data, size_t len) = 0;
  virtual void Listen() = 0;
};
}  // namespace Panda
